#pragma once
#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>

#define PROT__  8081
class UdpServer
{
    private:
      int sockfd;
      int port;

    public:
      UdpServer(int _port=PROT__):port(_port)
      {}
      ~UdpServer()
      {
        if(port>=0)
          close(sockfd);
      }

      bool Initudpserver()
      {
        sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(sockfd<0)
        {
          std::cerr<<"socket:"<<std::endl;
          return false;
        }

       struct sockaddr_in local;
       memset(&local,0,sizeof(local));
       local.sin_family=AF_INET;
       local.sin_port=htons(port);
       local.sin_addr.s_addr=inet_addr("0.0.0.0");//TNADDR_ANY;
      //local.sin_addr.s_addr=inet_addr("127.0.0.1"); 

       if( bind(sockfd, (struct sockaddr*)&local,sizeof(local) ) <0 )
       {
          std::cerr<<"bind 错误"<<std::endl;
          return false;
       }
       std::cout<<"bind 成功"<<std::endl;
       return true;
      }

      bool start()
      {
#define ABC 128
        char duffer[ABC];
        for(;;)
        {
          struct sockaddr_in peer;
          socklen_t len=sizeof(peer);
          memset(&peer,0,len);
          int size=recvfrom(sockfd,duffer,sizeof(duffer)-1,0,(struct sockaddr*)&peer,&len);
          if(size<0)
          {
            std::cout<<"recvfrom 错误"<<std::endl;
            continue;
          }
            
          std::string _ip=inet_ntoa(peer.sin_addr);
          int _port=ntohs(peer.sin_port);
          duffer[size]=0;
          std::cout<<_ip<<':'<<_port<<'#'<<duffer<<std::endl;
         // printf("%s:%d#%s\n",_ip.c_str(),_port,duffer);

          std::string result;
          std::string cmd=duffer;

          if(cmd=="ls")
          {
            int pipes[2];
            pipe(pipes);

            pid_t id=fork();
            if(id==0)
            {
              close(pipes[0]);
              dup2(pipes[1],1);
              execl("/usr/bin/ls","ls","-a","-l","-i",nullptr);
              exit(1);
            }
              
            close(pipes[1]);
            char c;
            while(1)
            {
              if(read(pipes[0],&c,1)>0)
              {
                result.push_back(c);
              }else 
              {
                break;
              }
            }

            wait(nullptr);
          }

          if(!result.empty())
          {
            cmd=result;
          }

         if( sendto(sockfd,cmd.c_str(),cmd.size(),0,(struct sockaddr*)&peer,len)<0)
         {
           std::cerr<<"sendto 错误"<<std::endl;
         }
        }
      }
};

